home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_053 / spreadsheet / lex.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  8KB  |  344 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  *        Lexical analyser
  3.  *
  4.  *        original by James Gosling, September 1982
  5.  *        modifications by Mark Weiser and Bruce Israel,
  6.  *            University of Maryland
  7.  *
  8.  *              More mods Robert Bond, 12/86
  9.  *        Major mods to run on VMS and AMIGA, 1/17/87
  10.  *
  11.  */
  12.  
  13.  
  14.  
  15. #include "sc.h"
  16. #include <ctype.h>
  17. #ifdef VMS
  18. #include "y_tab.h"
  19. #else
  20. #include "y.tab.h"
  21. #endif
  22.  
  23. extern char *malloc();
  24. char *strtof();
  25.  
  26. struct key {
  27.     char *key;
  28.     int val;
  29. };
  30.  
  31. struct key experres[] = {
  32. #include "experres.h"
  33.     0, 0};
  34.  
  35. struct key statres[] = {
  36. #include "statres.h"
  37.     0, 0};
  38.  
  39. #define ctl(x) ('x'&037)
  40.  
  41. yylex () {
  42.     register char *p = line+linelim;
  43.     int ret = -1;
  44.     while (isspace(*p)) p++;
  45.     if (*p==0) ret = -1;
  46.     else if (isalpha(*p)) {
  47.     char *tokenst = p;
  48.     register tokenl;
  49.     register struct key *tbl;
  50.     while (isalpha(*p)) p++;
  51.     if (p-tokenst <= 2) { /* a COL is 1 or 2 char alpha */
  52.         register  col;
  53.         ret = COL;
  54.         col = ((tokenst[0] & 0137) - 'A');
  55.         if (p == tokenst+2)
  56.         col = (col + 1)*26 + ((tokenst[1] & 0137) - 'A');
  57.         yylval.ival =  col;
  58.     } else {
  59.         ret = WORD;
  60.         tokenl = p-tokenst;
  61.         for (tbl = linelim ? experres : statres; tbl->key; tbl++)
  62.             if (((tbl->key[0]^tokenst[0])&0137)==0
  63.              && tbl->key[tokenl]==0) {
  64.             register i = 1;
  65.             while (i<tokenl && ((tokenst[i]^tbl->key[i])&0137)==0)
  66.                 i++;
  67.             if (i>=tokenl) {
  68.                 ret = tbl->val;
  69.                 break;
  70.             }
  71.             }
  72.         if (ret==WORD) { 
  73.         linelim = p-line;
  74.         yyerror ("Unintelligible word");
  75.         }
  76.     }
  77.     } else if ((*p == '.') || isdigit(*p)) {
  78.     register long v = 0;
  79.     char *nstart = p;
  80.     if (*p != '.') {
  81.         do v = v*10 + (*p-'0');
  82.         while (isdigit(*++p));
  83.     }
  84.     if (*p=='.' || *p == 'e' || *p == 'E') {
  85.         ret = FNUMBER;
  86.         p = strtof(nstart, &yylval.fval);
  87.     } else {
  88.             if((int)v != v)
  89.             {
  90.                 ret = FNUMBER;
  91.                 yylval.fval = v;
  92.             }
  93.             else
  94.             {
  95.  
  96.                 ret = NUMBER;
  97.                 yylval.ival = v;
  98.             }
  99.     }
  100.     } else if (*p=='"') {
  101.     /* This storage is never freed.  Oh well.  -MDW */
  102.     char *ptr;
  103.         ptr = p+1;
  104.         while(*ptr && *ptr++ != '"');
  105.         ptr = (char *)malloc((unsigned)(ptr-p));
  106.     yylval.sval = ptr;
  107.     p += 1;
  108.     while (*p && *p!='"') *ptr++ = *p++;
  109.     *ptr = 0;
  110.     if (*p) p += 1;
  111.     ret = STRING;
  112.     } else if (*p=='[') {
  113.     while (*p && *p!=']') p++;
  114.     if (*p) p++;
  115.     linelim = p-line;
  116.     return yylex();
  117.     } else ret = *p++;
  118.     linelim = p-line;
  119.     return ret;
  120. }
  121.  
  122. #define N_KEY 26
  123.  
  124. struct key_map {
  125.     char *k_str;
  126.     char k_val;
  127.     char k_index;
  128. }; 
  129.  
  130. struct key_map km[N_KEY];
  131.  
  132. initkbd()
  133. {
  134.     int i;
  135.  
  136.     /* cursor set mode */
  137.     km[0].k_str  = "\033OD"; km[0].k_val  = ctl(b);
  138.     km[1].k_str  = "\033OC"; km[1].k_val  = ctl(f);
  139.     km[2].k_str  = "\033OA"; km[2].k_val  = ctl(p);
  140.     km[3].k_str  = "\033OB"; km[3].k_val  = ctl(n);
  141.     /* cursor reset mode */
  142.     km[4].k_str  = "\033[D"; km[4].k_val  = ctl(b);
  143.     km[5].k_str  = "\033[C"; km[5].k_val  = ctl(f);
  144.     km[6].k_str  = "\033[A"; km[6].k_val  = ctl(p);
  145.     km[7].k_str  = "\033[B"; km[7].k_val  = ctl(n);
  146.     /* CSI arrows */
  147.     km[8].k_str  = "\233D";  km[8].k_val  = ctl(b);
  148.     km[9].k_str  = "\233C";  km[9].k_val  = ctl(f);
  149.     km[10].k_str = "\233A";  km[10].k_val = ctl(p);
  150.     km[11].k_str = "\233B";  km[11].k_val = ctl(n);
  151.     /* application keypad mode */
  152.     km[12].k_str = "\033Op"; km[12].k_val = '0';
  153.     km[13].k_str = "\033Oq"; km[13].k_val = '1';
  154.     km[14].k_str = "\033Or"; km[14].k_val = '2';
  155.     km[15].k_str = "\033Os"; km[15].k_val = '3';
  156.     km[16].k_str = "\033Ot"; km[16].k_val = '4';
  157.     km[17].k_str = "\033Ou"; km[17].k_val = '5';
  158.     km[18].k_str = "\033Ov"; km[18].k_val = '6';
  159.     km[19].k_str = "\033Ow"; km[19].k_val = '7';
  160.     km[20].k_str = "\033Ox"; km[20].k_val = '8';
  161.     km[21].k_str = "\033Oy"; km[21].k_val = '9';
  162.     km[22].k_str = "\033Om"; km[22].k_val = '-';
  163.     km[23].k_str = "\033Ol"; km[23].k_val = ',';
  164.     km[24].k_str = "\033On"; km[24].k_val = '.';
  165.     km[25].k_str = "\033OM"; km[25].k_val = ctl(m);
  166. }
  167.  
  168. nmgetch() 
  169. {
  170.     register int c;
  171.     register struct key_map *kp;
  172.     register struct key_map *biggest;
  173.     register int i;
  174.     int almost;
  175.     int maybe;
  176.  
  177.     static char dumpbuf[10];
  178.     static char *dumpindex;
  179.  
  180.     void timeout();
  181.  
  182.     if (dumpindex && *dumpindex)
  183.         return (*dumpindex++);
  184.  
  185.     c = ttgetc();
  186.     biggest = 0;
  187.     almost = 0;
  188.  
  189.     for (kp = &km[0]; kp < &km[N_KEY]; kp++) {
  190.     if (!kp->k_str)
  191.         continue;
  192.     if (c == (kp->k_str[kp->k_index] & 0xFF)) {
  193.         almost = 1;
  194.         kp->k_index++;
  195.         if (kp->k_str[kp->k_index] == 0) {
  196.         c = kp->k_val;
  197.                    for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  198.                 kp->k_index = 0;
  199.             return(c);
  200.         }
  201.     }
  202.     if (!biggest && kp->k_index)
  203.         biggest = kp;
  204.         else if (kp->k_index && biggest->k_index < kp->k_index)
  205.         biggest = kp;
  206.     }
  207.  
  208.     if (almost) return(nmgetch());
  209.  
  210.     if (biggest) {
  211.     for (i = 0; i<biggest->k_index; i++) 
  212.         dumpbuf[i] = biggest->k_str[i];
  213.     dumpbuf[i++] = c;
  214.     dumpbuf[i] = 0;
  215.     dumpindex = &dumpbuf[1];
  216.            for (kp = &km[0]; kp < &km[N_KEY]; kp++)
  217.         kp->k_index = 0;
  218.     return (dumpbuf[0]);
  219.     }
  220.  
  221.     return(c);
  222. }
  223.  
  224.  
  225. int dbline;
  226.  
  227. debug (fmt, a, b, c) {
  228.     move(2+(dbline++%22),80-60);
  229.     printw(fmt,a,b,c);
  230.     clrtoeol();
  231. }
  232.  
  233. /*
  234.  * This converts a floating point number of the form
  235.  * [s]ddd[.d*][esd*]  where s can be a + or - and e is E or e.
  236.  * to floating point. 
  237.  * p is advanced.
  238.  */
  239.  
  240. char *
  241. strtof(p, res)
  242. register char *p;
  243. double *res;
  244. {
  245.     double acc;
  246.     int sign;
  247.     double fpos;
  248.     int exp;
  249.     int exps;
  250.  
  251.     acc = 0.0;
  252.     sign = 1;
  253.     exp = 0;
  254.     exps = 1;
  255.     if (*p == '+')
  256.         p++;
  257.     else if (*p == '-') {
  258.         p++;
  259.         sign = -1;
  260.     }
  261.     while (isdigit(*p)) {
  262.         acc = acc * 10.0 + (double)(*p - '0');
  263.         p++;
  264.     }
  265.     if (*p == 'e' || *p == 'E') {
  266.         p++;
  267.         if (*p == '+')
  268.         p++;
  269.         else if (*p == '-') {
  270.         p++;
  271.         exps = -1;
  272.         }
  273.         while(isdigit(*p)) {
  274.         exp = exp * 10 + (*p - '0');
  275.         p++;
  276.         }
  277.     }
  278.     if (*p == '.') {
  279.     fpos = 1.0/10.0;
  280.     p++;
  281.     while(isdigit(*p)) {
  282.         acc += (*p - '0') * fpos;
  283.         fpos *= 1.0/10.0;
  284.         p++;
  285.     }
  286.     }
  287.     if (*p == 'e' || *p == 'E') {
  288.     exp = 0;
  289.     exps = 1;
  290.         p++;
  291.     if (*p == '+')
  292.         p++;
  293.     else if (*p == '-') {
  294.         p++;
  295.         exps = -1;
  296.     }
  297.     while(isdigit(*p)) {
  298.         exp = exp * 10 + (*p - '0');
  299.         p++;
  300.     }
  301.     }
  302.     if (exp) {
  303.     if (exps > 0)
  304.         while (exp--)
  305.         acc *= 10.0;
  306.     else
  307.         while (exp--)
  308.         acc *= 1.0/10.0;
  309.     }
  310.     if (sign > 0)
  311.         *res = acc;
  312.     else
  313.     *res = -acc;
  314.  
  315.     return(p);
  316. }
  317.  
  318. help () {
  319.     move(2,0);
  320.     clrtobot();
  321.     dbline = 0;
  322.     debug ("                 Cursor cmds:");
  323.     debug ("  ^n j next row       ^p k prev. row      ^g erase cmd");
  324.     debug ("  ^f l fwd col        ^b h back col       ^r redraw screen");
  325.     debug ("   0 $ first, end col");
  326.     debug ("                 Cell cmds:");
  327.     debug (" \" < > enter label       = enter value     x clear cell");
  328.     debug ("     c copy cell         m mark cell      ^t line 1 on/off");  
  329.     debug ("    ^a type value       ^e type expr.     ^v type vbl name");
  330.     debug ("                 Row, Column cmds:");
  331.     debug (" ar ac dup           ir ic insert      sr sc show");
  332.     debug (" dr dc delete        zr zc hide        pr pc pull");
  333.     debug (" vr vc value only        f format");
  334.     debug ("                 File cmds:");
  335.     debug ("     G get database      M merge database  T write tbl fmt");
  336.     debug ("     P put database      W write listing");
  337.     debug ("                 Misc. cmds:");
  338.     debug (" ^c, q quit              / copy region    pm pull (merge)");
  339.     debug ("                 Expression Operators");
  340.     debug ("  +-*/ arithmetic     ?e:e conditional   & | booleans");
  341.     debug (" < = > relations     <= >= relations      != relations");
  342.     debug ("       @sum(v1:v2)         @avg(v1:v2)       @prod(v1:v2)");
  343. }
  344.